package com.example.demo.controller;

import com.example.demo.domain.ResponseResult;
import com.example.demo.utils.OpenFileOnDeskTop;
import com.example.demo.utils.PdfUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;

@RestController
@Slf4j
public class ExcelController {

    @Autowired
    private Executor asyncTaskExecutor;

    @PostMapping("/upload")
    public ResponseResult fileUpload(@RequestParam("files") MultipartFile[] files,
                                     @RequestParam("rootPath") String rootPath) throws InterruptedException, IOException {
        // 确定项目根目录
        String projectRootPath = System.getProperty("user.dir");

        // 创建报告文件夹
        File reportFolder = createReportFolder(projectRootPath);

        // 读取模板文件
        Workbook templateWorkbook = readTemplate(projectRootPath + File.separator + "template");

        // 处理 PDF 文件并获取文件夹名称
        HashMap<String, HashMap<String, String>> map = new HashMap<>();
        double globalMax = 0;
        double globalMin = 0;
        String[] arrayFolderNames = processPdfFiles(files, map, asyncTaskExecutor);

        // 将数据写入 Excel 并保存
        writeExcelFromMap(rootPath, templateWorkbook, arrayFolderNames, map, globalMax, globalMin, reportFolder.getPath());

        // 返回响应结果
        return ResponseResult.okResult();
    }

    private File createReportFolder(String projectRootPath) {
        String reportFolderPath = projectRootPath + File.separator + "report";
        File reportFolder = new File(reportFolderPath);
        if (!reportFolder.exists()) {
            reportFolder.mkdirs(); // 创建多层文件夹
        }
        return reportFolder;
    }

    private Workbook readTemplate(String templatePath) throws IOException {
        File templateFile = new File(templatePath + File.separator + "template.xlsx");
        try (FileInputStream fis = new FileInputStream(templateFile)) {
            return new XSSFWorkbook(fis);
        }
    }

    private String[] processPdfFiles(MultipartFile[] files, HashMap<String, HashMap<String, String>> map, Executor asyncTaskExecutor) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(files.length);
        List<String> fileFolderNames = new ArrayList<>();

        for (MultipartFile file : files) {
            String[] pathSplits = Objects.requireNonNull(file.getOriginalFilename()).split("[/.]");
            String part = pathSplits[1];
            char lastChar = part.charAt(part.length() - 1);
            String tempDataName = lastChar + "-" + pathSplits[2];

            if (!fileFolderNames.contains(pathSplits[1])) {
                fileFolderNames.add(pathSplits[1]);
            }

            CompletableFuture.runAsync(() -> {
                try {
                    String[] content = PdfUtils.extractTextFromSinglePdf(file);
                    //todo 根据content提取关键数据到map
                    double max = Math.random(), min = Math.random();
                    HashMap<String, String> tempMap = new HashMap<>();
                    tempMap.put("max", String.valueOf(max));
                    tempMap.put("min", String.valueOf(min));
                    map.put(tempDataName, tempMap);
                } finally {
                    latch.countDown();
                }
            }, asyncTaskExecutor);
        }
        latch.await();
        return fileFolderNames.toArray(String[]::new);
    }

    /**
     *
     * @param extraParams 文件夹名称（根目录）
     * @param templateWorkbook xx
     * @param arrayFolderNames 文件夹名称
     * @param map 数据容器
     * @param globalMax 全局最大值
     * @param globalMin 全局最小值
     * @param reportFolderPath 报告文件夹输出路径
     */
    private static void writeExcelFromMap(String extraParams, Workbook templateWorkbook, String[] arrayFolderNames,
                                          HashMap<String, HashMap<String, String>> map, double globalMax, double globalMin,
                                          String reportFolderPath) throws IOException {
        // 从模板中获取工作表
        Sheet sheet = templateWorkbook.getSheetAt(0);
        // 计算全局最大值和最小值
        for (HashMap<String, String> tempMap : map.values()) {
            try {
                double tempMax = Double.parseDouble(tempMap.get("max"));
                double tempMin = Double.parseDouble(tempMap.get("min"));
                if (tempMax > globalMax) {
                    globalMax = tempMax;
                }
                if (tempMin < globalMin) {
                    globalMin = tempMin;
                }
            } catch (NumberFormatException e) {
                log.error("Invalid number format in tempMap: {}", e.getMessage());
            }
        }
        // 填充数据到工作表中
        int rowNum = 1;
        for (int i = 0; i < arrayFolderNames.length; i++) {
            for (int j = 1; j <= 7; j++) {
                HashMap<String, String> tempMap = null;
                String target = (i + 1) + "-" + j;
                if (map.containsKey(target)) {
                    tempMap = map.get(target);
                    Row row = sheet.createRow(rowNum++);
                    row.createCell(2).setCellValue(arrayFolderNames[i]);
                    row.createCell(3).setCellValue(Double.parseDouble(tempMap.get("max")));
                    row.createCell(4).setCellValue(Double.parseDouble(tempMap.get("min")));
                } else {
                    break;
                }
            }
            rowNum++;
        }
        // 在模板中创建一个新的行来保存全局最大值和最小值
        Row footerRow = sheet.createRow(rowNum);
        footerRow.createCell(0).setCellValue("Global Max");
        footerRow.createCell(1).setCellValue(globalMax);
        footerRow.createCell(2).setCellValue("Global Min");
        footerRow.createCell(3).setCellValue(globalMin);
        saveAndOpen(extraParams, reportFolderPath, templateWorkbook);
    }

    // 保存到report并打开
    private static void saveAndOpen(String extraParams, String reportFolderPath, Workbook templateWorkbook) throws IOException {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss");
        String formattedDateTime = "_" + now.format(formatter);

        String fileName = extraParams + formattedDateTime + ".xlsx";
        File excelFile = new File(reportFolderPath + File.separator + fileName);
        try (FileOutputStream fileOut = new FileOutputStream(excelFile)) {
            templateWorkbook.write(fileOut);
        }
        templateWorkbook.close();
        OpenFileOnDeskTop.openFile(excelFile);
    }
}